#include "Gconsole.h"
//TODO Remove reference to Ataxx
#include "Ataxx.h"

Gconsole::Gconsole(void) {
	quitFlag = false;
	initMapCommands();
	currGame = -1;
	debugger = Debug::getInstance();
}

Gconsole::Gconsole(std::vector<Game*> instances) {
	gameList = instances;
	quitFlag = false;
	initMapCommands();
	currGame = -1;
}

Gconsole::~Gconsole(void) {
	std::vector<Game*>::iterator it;
	for( it = gameList.begin(); it != gameList.end() ; it++ ) {
		delete (*it);
	}
	debugger = 0;
}

void Gconsole::AddGame(Game* gameInstance)
{
	gameList.push_back(gameInstance);
}

//This function is sought from stack overflow http://stackoverflow.com/questions/4654636/how-to-determine-if-a-string-is-a-number-with-c
bool is_number(const std::string& s)
{
std::string::const_iterator it = s.begin();
while (it != s.end() && isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}

void Gconsole::ParseCommand(std::stringstream& command) {
	//Get first command
	std::string word;
	command >> word;

	//Decide which command to execute
	switch (mapAllowedCommands[word]){
		case listG: std::cout << list() <<"\n";
			break;
		case debugG: {
			debugger->toggle();
					}
		case gameG: {   
						//Get parameter n of game command
						command >> word;
						//Give error message if parameter is not a number
						if(!is_number(word))
						{
							std::cout << word << " is not a number. Usage: game 1...n \n";
							break;
						}
						else
						{
							//Select game
							int tempInt = atoi(word.c_str());
							if ( tempInt <= static_cast<int>(gameList.size()) && tempInt > 0) {
								currGame = tempInt;
								std::cout << "Selected game: "<< currGame <<". " << gameList[currGame-1]->getName() << "\n";
							}
							else
							{
								std::cout << tempInt <<". is not a valid game number, type list to see games, select game with game 1...n\n";	
							}
						}
					}
					break;
		case quitG: quit(); // Changes the quit flag so that keepPlaying() returns false ( Main()'s read loop depends on keepPlaying() returning true)
			break;
		default: {
					//Command forwarded to game parser if not a valid game independent console command
					if(currGame != -1)
					{
					command.seekg(0);
					command.clear();
					gameList[currGame-1]->update(command);
					}
					else
					{
						debugger->debug();
					}
				 }
			break;
		}
	}

bool Gconsole::keepRunning() {
	return !quitFlag;
}


void Gconsole::quit() {
	quitFlag = true;
}

std::string Gconsole::list(){
	std::stringstream tempStringS;
	for(int i = 0; i < static_cast<int>( gameList.size() ); i++){
		if( i == 0) { 
			tempStringS << i+1 <<". " <<gameList[i]->getName();
		}
		else{ 
			std::string tempString2 = ". ";
			tempStringS << "\n" << i+1 << ". " << gameList[i]->getName();
		}
	}
	return tempStringS.str();
}

void Gconsole::initMapCommands()
{
	mapAllowedCommands["list"] = listG;
	mapAllowedCommands["game"] = gameG;
	mapAllowedCommands["quit"] = quitG;
	mapAllowedCommands["debug"] = debugG;
}